import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 Team: Name: Seungbeom Ma / Lok Kei Leong /Harini Padmanaban
 Reference: Wiki , discussion with classmates , lecture , lecture note, textbook
 Java api and example website.
 */


public class proxtest{
        
    static int totTokens,docCount=0;
    static double[] docScore;
    static int[] docFlag;
    static int cache=1;
    static String[] termArr = new String[20];
    @SuppressWarnings("unchecked")
        static ArrayList<Integer>[] docNumber = (ArrayList<Integer>[]) new ArrayList[20];
        static ArrayList<String> tokenList = new ArrayList<String>();
        static Hashtable<String,Integer> hashTermSearch = new Hashtable<String,Integer>();
        static Hashtable<Integer,Double> hashDocProxScore = new Hashtable<Integer,Double>();
        static Hashtable<String,ArrayList<Integer>> termDocList = new Hashtable<String,ArrayList<Integer>>();
        static Hashtable<String,ArrayList<Integer>> termIndexList = new Hashtable<String,ArrayList<Integer>>();
        static int tc = 0;
        static ArrayList<Integer> termkey = new ArrayList<Integer>();
        
        public static void main(String[] args) throws IOException {
                
                
                
                for(int p=0;p<20;p++)
                {
                        docNumber[p] = new ArrayList<Integer>();
                }
                /**
                 *  The first file Steam . It is reading the PointIndex
                 *   FileInputStream fstream1 = new FileInputStream(args[0]);
                 *  
                 */
   
                String query1 = new String(args[1]);
                String query_al = new String(args[2]);
                /**
                 *PointIndex: catching the String value from the stringTokenizer
                 * 
                 * */
                
                String strLine = null;              
                String keyword = null;     
                
                  
                int documentCounter = 1;
                int detectDoc = 0;
                /**
                 * HW2
                 * */
               
                int tracker = 0;      
                int HowManyTimeKeywordAppearInThisDoc = 0; 
                int savecounter = 0;        
                int howManyDocAppear = 0 ;
                int totalnumberofdocs = 1;
                Hashtable<Integer, Integer> HowmanytimeeachQueryApear =  new Hashtable<Integer,Integer>();
                /** AllDocContainer is containing all string of each doc
                * ex) AllDocContainer(1, "bob is good and bad")
                * ex) AllDocContainer(2, "this clas is really good and cool"
                */
                HashMap<Integer, String>  AllDocContainer = new HashMap<Integer, String>();             

                Hashtable<Integer , String> htDocCounter = new Hashtable<Integer , String>();
                /** this is the hashtable to store the document numbers which contain keyword*/
                Hashtable<Integer, Integer> DocsThatKeywordAppear = new Hashtable<Integer, Integer>();
                /** this is the hashtable to store how many time keyword is appear on each doc */
                Hashtable<Integer, Integer> HowManyTimeKeyWordAppearInEachDoc = new Hashtable<Integer, Integer>();
                /**this is arraylast to store the keyword from the text file.*/
                      
                        keyword = query1; 
                        StringBuffer testString = new StringBuffer();
                        FileInputStream fstream = new FileInputStream(args[0]);
                        DataInputStream in = new DataInputStream(fstream);
                        BufferedReader br = new BufferedReader(new InputStreamReader(in));
                        while ((strLine = br.readLine()) != null)   { 
                                StringTokenizer stringTokenizer = new StringTokenizer(strLine);
                                int EndOftheParagraph = 0;
                                /**
                                 * If paragrah is more than one like then we have to appead line + line 
                                 * therefore we need to sperate by empty space " " 
                                 * */
                                testString = testString.append(strLine + " "); 
                                                                                                
                        
                                Scanner sc = new Scanner (strLine);
                                while(sc.hasNext())
                                {
                                        sc.next();
                                        EndOftheParagraph++;
                                }                                     
                                if(EndOftheParagraph == 0)
                                {/** It is the end of paragraph, so we are reading new file*/
                                        
                                        savecounter++; /**increase counter for next document  */ 
                                        HowManyTimeKeywordAppearInThisDoc = 0;/** since we are moving to new doc*/                                 
                                }
                                if(stringTokenizer.countTokens() == 0)
                                { 		/**if token is done it's end of doc
                                         * testString = stringBuffer 
                                         * need to convert stringBuffer to String 
                                         * `SortAllDoc <documentCounter = doc_id  , sec = praragraph for each document
                                         * */
                                        String sec = testString.toString();
                                        AllDocContainer.put(documentCounter, sec);
                                        
                                        /**
                                         * One document is done, so We need to clean StringBuffer
                                         * In order to prepare for next document, we need to delete
                                         * content of StringBuffer testString.. 
                                         * */
                                        testString.delete(0,testString.length() );
                                        documentCounter++; 
                                        totalnumberofdocs++;
                                        
                                        /** if it is moving to new document, we need to initialize 
                                        * HowManyTimeKeywordAppearInThisDoc again for counting keyword from
                                        *  another doc      */                                                                                                                             
                                }
                                while(stringTokenizer.hasMoreElements()){ 
                                        String lowercaseWordFromParagraph = stringTokenizer.nextToken().toLowerCase();
                                        if(lowercaseWordFromParagraph.equals(keyword)){ 
                                                
                                                HowManyTimeKeywordAppearInThisDoc++; /** increase number of keyword in this document*/
                                                /** this hashtabl is recording how many time keyword is appearing in each document*/
                                                HowManyTimeKeyWordAppearInEachDoc.put(savecounter, HowManyTimeKeywordAppearInThisDoc);                                                                                                              
                                                if(!htDocCounter.containsKey(documentCounter))                                                     
                                                {/** If new document contains keyword  
                                                         *
                                                         * htDocCounter => keyword
                                                         * DocsThatKeywordAppear -> document id that keyword in the htDocCounter 
                                                         * */
                                                        htDocCounter.put(documentCounter, lowercaseWordFromParagraph); /** we put keyword in the hashtable*/
                                                        DocsThatKeywordAppear.put(detectDoc, documentCounter); /** we also put document number in the hashtable */
                                                        
                                                        detectDoc++; /** for next keyword, we increare key in hashtable*/
                                                        
                                                        howManyDocAppear++;           

                                                }          
                                                
                                                           

                                        }
                                        
                                }       
               
                        
                        
/** howManyDocAppear:How many doc has "keyword" 
 * keyWordIndex: total number of times appear in docs
 * list1: which doc contains "keyword"
 * list2: how many time appear the "keyword" in the List1
 * 
 * 
 * */
        
                                String lastStrLine =  " ";
                                lastStrLine = strLine.toString();
                                AllDocContainer.put(documentCounter, lastStrLine);


/**
 * tracker: denominator of idf
 */
tracker =  tracker + howManyDocAppear;


/** To make display form, we copy two hashtables values to arraylist.*/
        ArrayList<Integer> list1 
                = new ArrayList<Integer>(DocsThatKeywordAppear.values());
        ArrayList<Integer> list2 
        = new ArrayList<Integer>(HowManyTimeKeyWordAppearInEachDoc.values());
        ReverceList(list1);
        ReverceList(list2);
/** HowmanytimeeachQueryApear
 * Key = docuement number
 * key2 = homany time query appear in the each docs
 */
for(int printerIndex = 0 ; printerIndex <list2.size() ; printerIndex++)
{

        HowmanytimeeachQueryApear.put(list1.get(printerIndex),list2.get(printerIndex));
        
}
                        /** one looping is done , so we need to re-set all variable
                        * and hashtable for another keyword*/
                        
                        howManyDocAppear = 0;
                        savecounter = 0;
                        detectDoc =0;
                    
                        htDocCounter.clear();
                        DocsThatKeywordAppear.clear();
                        HowManyTimeKeyWordAppearInEachDoc.clear();
                                    
                } 

                        
                        Iterator<Entry<Integer, Integer>>  it;
                        Map.Entry entry;

            if (query_al.equals("cosine")){
  
                                int numofdoc = AllDocContainer.size();
                                int len=0,next=0;
                                calculate(query1,numofdoc, AllDocContainer);
                                                               
                                while(termArr[next] != null)
                                {
                                        len++;
                                        next++;
                                }
                                
                                for (int i=0;i<len;i++)
                                {       
                                        updateDocList(termArr[i],AllDocContainer,numofdoc);
                                }

                if (CountingWord(query1) == 1){
                        
                        double tf = 0.0;
                    ArrayList<Integer> docidList1 = new ArrayList<Integer>();
                    ArrayList<Double> rankList1 = new ArrayList<Double>();
                    ArrayList<Double> sortList1 = new  ArrayList<Double>();
                        double idf = 
                                        Math.log((double)((double)totalnumberofdocs/(double)tracker))/Math.log(2.0);
            

                    it = HowmanytimeeachQueryApear.entrySet().iterator();
                    while (it.hasNext()) {
                        entry = it.next();
                                
                  
                                int temp = 0;
                                while(true){    
                                 temp =  (Integer) entry.getValue();                                         
                                tf = (Math.log(temp)/Math.log(2) )+ 1;
                           
                                break;
                            }
                            float tfidf = (float)idf * (float)tf;
                            
                                docidList1.add((Integer)entry.getKey());
                                rankList1.add((double) tfidf);
                   
                                sortList1.add((double) tfidf);
                           
                    }
                    Collections.sort(sortList1);
                    Collections.reverse(sortList1);
                    int luisatracker = 0;
                    for(int matchLuisa = 0 ; matchLuisa < sortList1.size() ; matchLuisa++)
                    {
                   
                         for(int bob = 0 ; bob < sortList1.size() ; bob++ ){

                                 if(sortList1.get(matchLuisa).equals(rankList1.get(bob)))
                                 {
                                        luisatracker++;
                                      
                                         System.out.println("( " + docidList1.get(bob) + " , " + sortList1.get(matchLuisa) +" )" );
                                         
                                 }
                                 
                         }
                          if(luisatracker == sortList1.size())
                          {
                                  break;
                                  
                          }
                    } 
                }
                    else 
                    {
                        /**
                         * wordscontainer: storing each word in the
                         * query. 
                         * if query is "Bob ma" 
                         * wordscontainer[0] = Bob
                         * wordscontainer[1] = ma
                         */
                  
                    	
                         String[] wordscontainer = returnWord(query1);
                       
                         /**containsDocnumberthatcontainAllQuery will contain doc number
                         * which contains all words in query.
                         * tfidfarray array contains tfidf value for each docs*/
                         float [] tfidfarray = new float[AllDocContainer.size()+1];
                         int AllDocIndex = 1;
                         int counter = 0;
                         int whatsize = 0;
                         ArrayList<String> aListNumbers = new ArrayList<String>();
                         for(int i = 1 ; i < AllDocContainer.size()+1 ; i++ )
                         {
                                 for(int j = 0 ; j < wordscontainer.length ; j++)
                                 {

                                         String[] numbers = AllDocContainer.get(i).split(" ");

                                         for(int q=0; q< numbers.length; q++)
                                         {
                                                 
                                                 aListNumbers.add(numbers[q]);
                                         }
                                         
                                         if(aListNumbers.contains(wordscontainer[j]))
                                         {
                                                 counter++;
                                                 
                                         }
                                         
                                 }
                                 aListNumbers.clear();
                                 if(counter == wordscontainer.length )
                                 {
                                         whatsize++;
                                         
                                 }
                                 counter=0;
                                 
                         }
                        ArrayList<Integer> docidList = new ArrayList<Integer>();
                        ArrayList<Double> rankList = new ArrayList<Double>();
                        ArrayList<Double> Luisa = new  ArrayList<Double>();
                         
                         while(AllDocIndex <= AllDocContainer.size())
                         {
                                 
                             tfidfarray[AllDocIndex] = 
                                         getTFIDF(wordscontainer,AllDocContainer,AllDocIndex , AllDocContainer.size(), whatsize);
                             AllDocIndex++;
                         }
                            
                             for(int index3 = 1 ; index3 <= AllDocContainer.size(); index3++){
                                  /** if every anyterm is not appear in the doc then 
                                   * getTFIDF will return -9999999
                                   * so skip print part
                                   */
                                  if(-9999999 != tfidfarray[index3]){
                                       
                                                docidList.add(index3);
                                                rankList.add((double) tfidfarray[index3]);
                               
                                                Luisa.add((double) tfidfarray[index3]);
                                                
                                  }
                             }
                             Collections.sort(Luisa);
                             Collections.reverse(Luisa);
                             
                             ArrayList<Integer> preventdup = new ArrayList<Integer>();
                             for(int matchLuisa = 0 ; matchLuisa < Luisa.size() ; matchLuisa++)
                             {
                            
                                 for(int bob = 0 ; bob < Luisa.size() ; bob++ ){

                                         if((Luisa.get(matchLuisa).equals(rankList.get(bob))&&(!(preventdup.contains(docidList.get(bob))))))
                                         {
                                                 
                                                 preventdup.add(docidList.get(bob));
                                                 System.out.println("( " + docidList.get(bob) + " , " + Luisa.get(matchLuisa) +" )" );
                                                 
                                         }
                                 }
                             }                                            
                        }                               

                        }
                        else if (query_al.equals("boolean")) {
                                
                                int numberofDoc = AllDocContainer.size();
                                calculate(query1,numberofDoc, AllDocContainer);
                                ArrayList<Integer> docidList1 = new ArrayList<Integer>();
                                ArrayList<Double> rankList1 = new ArrayList<Double>();
                                ArrayList<Double> Luisa1 = new  ArrayList<Double>();
                                 
                                
                                for(int index=0; index< numberofDoc;index++)
                                {
                                        if(docFlag[index]==1)
                                        {
                                             
                                                docidList1.add((index+1));
                                                rankList1.add(docScore[index]);
                                                Luisa1.add(docScore[index]);
                                        }
                                }
                                
                                                               Collections.sort(Luisa1);
                                Collections.reverse(Luisa1);
                                ArrayList<Integer> preventdup1 = new ArrayList<Integer>();
                                for(int matchLuisa1 = 0 ; matchLuisa1 < Luisa1.size() ; matchLuisa1++)
                                {
                               
                                    for(int bob1 = 0 ; bob1 < Luisa1.size() ; bob1++ ){

                                            if((Luisa1.get(matchLuisa1).equals(rankList1.get(bob1))&&
                                            			(!(preventdup1.contains(docidList1.get(bob1))))))
                                            {
                                                   
                                            	preventdup1.add(docidList1.get(bob1));
                                                    System.out.println("( " + docidList1.get(bob1) + " , " + Luisa1.get(matchLuisa1) +" )" );
                                                    
                                            }
                                    }
                                } 
                                
                                
                        }
                        else if (query_al.equals("proximity"))
                        {
                        	String[] proArray=returnWord(query1);
                        	int noOfDoc = AllDocContainer.size();
                        	
                        	for(int index=1;index<=noOfDoc;index++)
                        	{	
                        		findTermIndex(proArray,AllDocContainer,index);
                        	}	
                        	System.out.print("sadas "  + termkey);
                        	for(int finalindex = 0 ; finalindex < hashDocProxScore.size() ; finalindex++)
                        	{
                        		System.out.println("DocID " + finalindex +  " prox score " + hashDocProxScore.get(termkey.get(finalindex)) );
                        	}
                        }
                        	
                        else{
                                System.out.println("must choose one");
                                
                        }
                        


        }
        
	/**
	 * Helper Function 
	 */
    
	/** 
	 *	For Printing New Line
	 */
        public static void NewLine()
        {System.out.println();}
	/** 
	 * For reversing the ArrayList
	 */
        public static void ReverceList(ArrayList<Integer> al)
                {Collections.reverse(al);}
       /**
        *Clearing contents inside of Hashtable
        *
        public static void free(Hashtable ht)
                {ht.clear();}*/
       /**
     	* @param word: it is the querry term
     	* @return return the number of words in the querry
     	* Counting how many works in the String.
     	*/
        public static int CountingWord(String word)
        {
                 String[] arr = word.split(" ");
                 int length = arr.length;               
                 return length;
                
        }
        /**
         * @param1 term the signle word of the term from querry
         * @param2 docNum document number
         * @param3 hm hashmap that has all to document
         * @return true or false to check word is inside the document or not
         */
        public static boolean checkWordIsInsideOrNot
                        (String term , int docNum ,  HashMap<Integer, String> hm )
        {
                String text = hm.get(docNum);
                String patternString = " " + term+" " ;
                String patternString1 = term+" ";
                Pattern pattern = Pattern.compile(patternString);
                Pattern pattern1 = Pattern.compile(patternString1);
                Matcher matcher = pattern.matcher(text);
                Matcher matcher1 = pattern1.matcher(text);
                if (matcher1.find() || matcher.find()){
                	return true;
                }else{
                	return false;
                }
                //return (matcher.find()) ? true : false;
        }
        
	/**
	 * @param1 word: This is the term to past in for spliting to words
	 * @return arr:  return to a String array that has splitted words. 
	 * spliting each words from the String 
	 * and sort into array and return the word containers
	 */
        public static String[] returnWord(String word)
        {
                 String[] arr = word.split(" ");                   
                 return arr;    
        } 
        /** Function: Returning  numnber of term in the each document
         * 
         * @param1 TermArray: This array contain words in query like [1] = "Hello" [2] ="new"
         * @param2 docHashMap: contain each docs  like docHashMap = docHashMap
         * @return case1: if doc contains all words will return {hello=2, new=1}
         * @return case2:query [1] = "Hello" [2] ="new" [3] = "cool"
         * then doc is missing "cool", so it will return -9999999 
         * First, get each how many times words is in the doc 
         * Second once we get the all value and all term is appear
         * then go to else case and using iterator to get int value from the keyword "term"
         * Third, we call CalTF and CalIDF to get each value
         * fourth , we cal tf-idf value and return it
         */
        public static float getTFIDF
          (String [] TermArray , HashMap <Integer, String> docHashMap, int docnumber , int totalnumberofdocs , int whatsize)
        {
                int reVal = 0;
               
                String doc = docHashMap.get(docnumber).toString();
                HashMap <String, Integer> failmap = new HashMap <String, Integer>();
                int index ;
                String keyword = " ";
              
                Map<String,Integer> hmap= new HashMap<String,Integer>();
                for(index = 0 ; index < TermArray.length ; index++)
                {
                        for(String Str : doc.split(" "))
                        {
                                keyword = Str;
                            
                                if(TermArray[index].equals(Str))
                                {
                                        reVal++;        
                                        hmap.put(keyword, reVal);
                                }
                                
                        }
                        reVal = 0;
                }
                
                if((hmap.size() != TermArray.length))
                {
                        return -9999999;
                }
                else
                {
                
                        Set set = hmap.entrySet();
                        Iterator it = set.iterator();
                        int valuefortf = 0;
                        double tf = 0.0;
                        double idf = 0.0;
                        float tfidf;
                        float finalValue = 0;
                        while(it.hasNext())
                        {
                                Map.Entry m = (Map.Entry)it.next();
                                valuefortf = (Integer)m.getValue();
                                tf = CalTF(valuefortf);
                                idf=CalIDF(totalnumberofdocs, whatsize);
                                tfidf = (float)tf * (float)idf;
                                finalValue = tfidf;
                        }

                        return finalValue;
                }
                
        }
        
    
    /**
     * @param howmaytimetermInKeyWord: how many time the term appear in one document
     * @return tf value
     * cal TF value for each term
     * */
    static double CalTF(int howmaytimetermInKeyWord)
    {
                                            
            double  tf = 
            (Math.log(howmaytimetermInKeyWord)/Math.log(2) )+ 1;
            
            return tf;
    }
        
    /**
     * @param1 totalnumberOfDocs = the total numbers of document
     * @param2 howmaytimetermInKeyWord: how many time the term appear in the file
     * @return value of idf
     * cal IDF
     */
    static double CalIDF(int totalnumberOfDocs , int howmaytimetermInKeyWord)
    {
            double idf = 
            Math.log((double)((double)totalnumberOfDocs/(double)howmaytimetermInKeyWord))/Math.log(2);

            return idf;
            
    }

    /**
     * @param1 term = the term in the given query
     * @param2 hm: a hashmap that store the index and the query words
     * @param3 totalDocs: how many time the term appear in the file
     * helper function for next and prev to date document list
     */
        
        static void updateDocList(String term, HashMap<Integer,String> hm, int totalDocs)
        {
                String text = new String();
                int i=0,temp=0;
                temp = totalDocs;
        
                for(i=1;i<=temp;i++)
                {       
                        text = hm.get(i);
                        String patternTerm = " "+term +" ";
                        
                        Pattern pattern = Pattern.compile(patternTerm);
                        
                        Matcher matcher = pattern.matcher(text);
                        
                        if(matcher.find() || matcher.find())
                        {
                                
                             
                                docNumber[docCount].add(i);
                                
                        }
                }
                
                termDocList.put(term,docNumber[docCount]);
                docCount++;
                }

        /**
         * @param1 term: the term from querry
         * @param2 docNo: document number
         * @param3 hm hashmap that has all to document
         * @return 0 or 1 for finding the term in the document or not.
         */    
        static int searchTerm (String term, int docNo , HashMap<Integer, String> hm)    
        {
                String text = new String();
                
                text = hm.get(docNo);
                docScore[docNo-1]= ((double)1/((double)docNo +(double)1));
                
             
                String patternTerm = " "+term +" ";
                String patternString1 = term+ " ";
                Pattern pattern = Pattern.compile(patternTerm);
                
                Pattern pattern1 = Pattern.compile(patternString1);
                Matcher matcher = pattern.matcher(text);
                Matcher matcher1 = pattern1.matcher(text);
                
                
                if(matcher.find() || matcher1.find())
                        return 1;
                else
                        return 0;
        }

       /**
        * helper function for eval boolean expresstion
        */        
        static int eval()
        {
                int op1=0,op2=0,size=0;
                String token;
                size = tokenList.size();
                Stack<Integer> stack = new Stack<Integer>();
                
                
                for(int i=size-1;i>=0;i--)
        {
            token = tokenList.get(i);
            while( !token.equals("*") && !token.equals("+") && !token.equals("-"))
            {
                stack.push((Integer) hashTermSearch.get(token));   
                i--;
                if(i>-1)
                {       token = tokenList.get(i);}
                else
                        {break;}
            }
                if(token.equals("*") || token.equals("+") || token.equals("-") )
            {
                if(token.equals("*"))
                {
                        op1=stack.pop();
                        op2=stack.pop();
                        if(op1 ==1 && op2==1)
                                op1=1;
                        else
                                op1=0;
                        stack.push(op1);
                }
                if(token.equals("+"))
                {
                        op1=stack.pop();
                        op2=stack.pop();
                        if( op1==1 || op2==1)
                        {op1=1;}
                        else
                        {op1=0;}        
                        stack.push(op1);
                }
                if(token.equals("-"))
                {
                        op1=stack.pop();
                        if(op1==1)
                        { op1=0;}
                        else if(op1 == 0)
                        {op1=1;}
                        stack.push(op1);
                }       
             }
         }
                return (stack.pop());
        }            
        
     	 /**
      	  * @param1 s the signle word of the term from querry
	  * @param2 numofdoc document number
	  * @param3 hm hashmap that has all to document
	  * @return 0 or 1 to caluclate boolean expresstion 
      	  */
        
        public static int calculate(String s , int numofdoc , HashMap<Integer, String> hm)
        {
                int n,i=0,flag=0,j=0,k=0,totTerms=0,containsOpr=0;
                char ch;
                String word;
                int index=0;

                docScore=new double[numofdoc];
                docFlag=new int[numofdoc];
                StringBuilder builder = new StringBuilder();
                
                
                n=s.length();
                
                while(index<n)
                {
                        ch=s.charAt(index);
                        if((ch == '*') || (ch == '+') || (ch == '-'))
                        {
                                containsOpr=1;
                                break;
                        }
                        index++;
                }
                
                for(i=0;i<n;i++)
                {
                        ch= s.charAt(i);
                        
                        while(ch != '+'  && ch!='-' && ch!='*' && ch!=' ')
                        {                               
                                flag=1;
                                builder.append(ch);
                                i++;
                                if(i<n)
                                {
                                        ch= s.charAt(i);
                                }
                                else
                                break;  
                        }
                        if(flag == 1)
                        {
                                flag=0;
                                totTokens++;
                                totTerms++; /*Number of words in the query*/
                                word = builder.toString();
                                tokenList.add(word);
                                termArr[k]=word;
                                k++;
                                builder.delete(0,builder.length());
                                word= " ";
                        }
                        
                        if((ch == '*') || (ch == '+') || (ch == '-'))
                        {       
                                totTokens++;   /**tokens in the query*/
                                tokenList.add(Character.toString(ch));
                        }       
                        
                }
                
                if(containsOpr == 0)
                {
                        String temp;
                        int size = tokenList.size(),m=0;
                        
                        if(size > 1)
                        {       
                                for(m=size-1;m<=0;m--)
                                {
                                        temp = tokenList.get(m);
                                        tokenList.add((size+m),temp);
                                }
                                m=0;
                                temp = "*";
                                for(m=0;m<size-1;m++)
                                {
                                        tokenList.add(m,temp);
                                }
                        }                       
                }
                
                for(i=0;i<numofdoc;i++)
                {
                        for(j=0;j<totTerms;j++)
                        {/**
                         * here i+1 is the doc number
                        */
                                hashTermSearch.put(termArr[j],searchTerm(termArr[j],i+1, hm)); 
                        }
                        docFlag[i]=eval();
                }
        
                return 0;
        }
        
        static void findTermIndex(String[] term, HashMap<Integer, String> hm,int docNo)    
        {
                int index=0,startIndex=0,wordIndex=0;
        		String text = new String();
        		String regex = new String();   
        		ArrayList<Integer> indexList = new ArrayList<Integer>();
                
                text = hm.get(docNo);
                String[] doc = text.split(" ");
                
                for(index=0;index<term.length;index++)
                {	
                	for(int i=0;i<doc.length;i++)
                	{
                		if(term[index].equals(doc[i]))
                		{
                			indexList.add(i+1);
                		}
                	}
                	               	
                	termIndexList.put(term[index],indexList);
                	indexList = new ArrayList<Integer>(); 
                     
               }	
               calcProximityScore(termIndexList, docNo, term);
               
        } 
        
        static void calcProximityScore(Hashtable<String,ArrayList<Integer>> ls,int docNo,String[] term)
        {
        	int i=0,j=0,u=10000,v=0,position=0,temp=0;
        	double proximityScore=0.0;
        	       	       	
        	while( position >= 0 )
        	{
        		u=10000;
        		for (i=0; i< term.length; i++)
        		{
        			temp=next(ls,position,term[i]);
        			if(v < temp && temp != 10000)
        			{
        				v=temp;
        			}
        			if( temp == 10000 )
        			{	
        				v=temp;
        				position = -1;
        				break;
        			}	
        		}
        		if(v!=10000) 
        		{
        			for (i=0; i< term.length; i++)
            		{
            			temp=prev(ls,v+1,term[i]);
            			if(u > temp && temp != -1)
            			{
            				u=temp;
            				position=temp;
            			}
            			if(temp == -1 || u==10000)
            			{
            				position = temp; 
            				break;
            			}
            		}	
        			
        		}
        		if( position != -1)
        		{	
        			proximityScore = proximityScore + ((double)(1.0)/ (((double)v-(double)u) + 1.0));
        			termkey.add(docNo);
        			System.out.println("Doc No " + docNo + " proximityScore " + proximityScore);
        			System.out.println("(u,v)" + u + "," + v);        			
        			hashDocProxScore.put(docNo,proximityScore);
        		}
        	}	
          //      System.out.println("hashDocProxScore " + hashDocProxScore);	
        }
        
        static int next(Hashtable<String,ArrayList<Integer>> ls,int position,String term)
        {
        	int index=0,v=0;
        	
        	while(index < ls.get(term).size() && ls.get(term).get(index) <= position)
        	{
        		index++;
        	}
        	if( index >= ls.get(term).size() )
        	{
        		v=10000;
        	}
        	else
        		v=ls.get(term).get(index);
        	return v;
        }
        
        static int prev(Hashtable<String,ArrayList<Integer>> ls,int position,String term)
        {
        	int index=0,u=0;
        	
        	index= ls.get(term).size()-1;
        	
        	while(index >= 0 && ls.get(term).get(index) >= position)
        	{
        		index--;
        	}
        	if( index < 0 )
        		u=-1;
        	else
        		u=ls.get(term).get(index);
        	
        	return u;
         }
        
        /**
         *  @param1 key: the term to serach in whole file
         *  serarch whole document to find the term  
         *  where it first appear
         *  @return the fist document id where the term appear 
         */      

    public static int first(String key)
    {
        int first = 0;
        
        ArrayList<Integer> temp = termDocList.get(key);
      
        if ( temp.get(0) != 0){
                first = temp.get(0);
                return first;
        }else
                return 0;

 
    }

        /**
         *  @param1 key: the term to serach in whole file
         *  serarch whole document to find the term  
         *  where it last appear
         *  @return the last document id where the term appear 
         */   
        public static int last(String key)
        {
        
        int last = 0;
        
        ArrayList<Integer> temp = termDocList.get(key);
        
        int size=temp.size();
       
        if (size != 0){
                
                last = temp.get(size-1);
                return last;
        }
        else
                return 0;
        }

	/**
	 * @param1 s: it is the term from the query
	 * @param2 low: starting position
	 * @param3 hight: end position
	 * @param4 current: current position
	 * @param5 temp: arraylist of integer that has docid 
	 * @return the position of the document 
	 */
        public static int binarysearch(String s, int low, int high, int current,ArrayList<Integer> temp)
        {
                double mid=0;
                                
                while((high-low) >1)
                {
                        mid = Math.floor((double)(low + high)/(double)2);
                        
                        if( temp.get((int)mid) <= current)
                                low = (int)mid;
                        else
                                high = (int)mid;
                }
                
        return high;
        }

	/**
	 * @param1 s: it is the term from the query
	 * @param2 low: starting position
	 * @param3 hight: end position
	 * @param4 current: current position
	 * @param5 temp: arraylist of integer that has docid 
	 * @return the position of the document 
	 */
        
        public static int binarysearchprev(String s, int low, int high, int current,ArrayList<Integer> temp)
        {
                double mid=0;
                                
                while((high-low) >1)
                {
                        mid = Math.floor((double)(low + high)/(double)2);
                        
                        if( temp.get((int)mid) < current)
                                low = (int)mid;
                        else
                                high = (int)mid;
                }
                
        return low;
        }
        
        /**
         * @param1 the term to serach in document
         * @param2 the given document id to start 
         *  serarch prev document that has the term
	 * @return prev document id
         *  where preview appear in given document id
         */
        public static int prev(String key, int current)
        {
        
		int temp = first(key);
		int next_id = next(key, temp);
		int last_term = last(key);

		
		int result = 0;
		if (next_id >= current){
			return temp;
		}
		else if (current > last_term){
			current = last_term;
			return current;
		}
		else{
		 for ( int i = next_id; i < current; i++){
			if ( next(key,i) >= current)
				result = next(key, i-1);
				

		}

		}
		return result;
    }
 
        /**
         * @param1 the term to serach in document
         * @param2 the given document id to start 
         *  serarch next document that has the term
	 * @return next document id
         *  where next appear in given document id
         */

        public static int next(String term, int current)
        {
                ArrayList<Integer> temp = termDocList.get(term);
                
                
                int lt=0,low=0,high=0,jump=0;
                lt=temp.size();
                
                if((lt == 0) || (temp.get(lt-1) < current))
                {return 0;}
                if(temp.get(0) > current)
                {
                        cache = 0;
                        return temp.get(cache);
                }
                if((cache>0) && (temp.get(cache-1) <= current))
                        low=cache-1;
                else
                        low=0;
                
                jump=1;
                high=low+jump;
                
                while ((high < lt) && (temp.get(high) <= current))
                {
                        low = high;
                        jump=(2*jump);
                        high = low + jump;
                }
                if(high > lt)
                {
                        high = lt;
                }
                cache = binarysearch(term,low,high,current,temp);
                
                return temp.get(cache);
        }
        

        
        static int CountDocs(String term){
                int x = 0;
                int count = 0;
                x = next(term, 0);
                
                while (x != 0){
                count++;
                cache = tc;
                x = next(term,x);
                }
                return count;

                }
        
}               

